package com.example.javatool.recallfile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class FileMover {

    /**
     * 读取 server_file.txt 文件，获取第二列的值
     * @param serverFilePath server_file.txt 文件路径
     * @return 包含 server_file.txt 第二列值的集合
     * @throws IOException 当文件读取出错时抛出
     */
    private static Set<String> readServerFile(String serverFilePath) throws IOException {
        Set<String> serverMd5Set = new HashSet<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(serverFilePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(",");
                if (parts.length >= 3) {
                    serverMd5Set.add(parts[2]);
                }
            }
        }
        return serverMd5Set;
    }

    /**
     * 读取 mail_file_md5.txt 文件，构建 MD5 值与文件名的映射
     * @param mailFileMd5Path mail_file_md5.txt 文件路径
     * @param serverMd5Set 包含 server_file.txt 第二列值的集合
     * @return MD5 值与文件名的映射
     * @throws IOException 当文件读取出错时抛出
     */
    private static Map<String, String> readMailFileMd5(String mailFileMd5Path, Set<String> serverMd5Set) throws IOException {
        Map<String, String> md5ToFileNameMap = new HashMap<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(mailFileMd5Path))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(" ");
                if (parts.length >= 2 && serverMd5Set.contains(parts[1])) {
                    md5ToFileNameMap.put(parts[1], parts[0]);
                }
            }
        }
        return md5ToFileNameMap;
    }

    /**
     * 移动匹配的文件到 "服务器已有" 文件夹
     * @param md5ToFileNameMap MD5 值与文件名的映射
     * @param sourceDir 源文件目录
     * @throws IOException 当文件移动出错时抛出
     */
    private static void moveFiles(Map<String, String> md5ToFileNameMap, String sourceDir) throws IOException {
        File sourceDirectory = new File(sourceDir);
        if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
            throw new IllegalArgumentException(sourceDir + " 不是有效的目录");
        }

        File targetDir = new File(sourceDirectory, "服务器已有");
        if (!targetDir.exists()) {
            if (!targetDir.mkdirs()) {
                throw new IOException("无法创建目标目录: " + targetDir.getAbsolutePath());
            }
        }

        for (String fileName : md5ToFileNameMap.values()) {
            File sourceFile = new File(sourceDirectory, fileName);
            if (sourceFile.exists() && sourceFile.isFile()) {
                Path sourcePath = sourceFile.toPath();
                Path targetPath = Paths.get(targetDir.getAbsolutePath(), fileName);
                Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
                System.out.println("文件 " + fileName + " 已移动到 " + targetDir.getAbsolutePath());
            }
        }
    }

    /**
     * 主处理方法，对比文件并移动匹配的文件
     * @param mailFileMd5Path mail_file_md5.txt 文件路径
     * @param serverFilePath server_file.txt 文件路径
     * @param sourceDir 源文件目录
     * @throws IOException 当文件操作出错时抛出
     */
    public static void compareAndMoveFiles(String mailFileMd5Path, String serverFilePath, String sourceDir) throws IOException {
        Set<String> serverMd5Set = readServerFile(serverFilePath);
        Map<String, String> md5ToFileNameMap = readMailFileMd5(mailFileMd5Path, serverMd5Set);
        moveFiles(md5ToFileNameMap, sourceDir);
    }

    public static void main(String[] args) {
        String mailFileMd5Path = "D:\\email\\mail_file_md5.txt";
        String serverFilePath = "D:\\email\\server_file.txt";
        String sourceDir = "D:\\email\\附件";
        try {
            compareAndMoveFiles(mailFileMd5Path, serverFilePath, sourceDir);
            System.out.println("文件对比和移动操作完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
